iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 5
1

介紹了幾天,也稍微玩了一些功能,是不是快受不了 Web Audio API 文件導讀啦 XD?

那麼就用已經玩到的部分,來做個簡單的吉他定音器吧!

吉他定弦

一般的民謠 / 古典吉他有六條弦,標準調弦會分別定弦在 E2、A2、D3、G3、B3、E4;依照我們目前練習過的內容,可以先來練習做出 可調整基準音 + 可設定調弦法 + 分別撥放單弦聲音 的吉他定音器。

guitar

在 Web Audio API 中,若要播放出不同的音高,必須要先計算出各音高的頻率。所以,接著要先來上個簡單的樂理課 & 數學課啦~

如果樂理的部分有表達不清或錯誤的地方,歡迎各路大神協助指正,感謝!

半音

大家應該都有看過鋼琴之類的鍵盤樂器吧?在鍵盤樂器上,白鍵的部分就是一般的音階(C 大調自然音階;C、D、E、F、G、A、B),而黑鍵則是相對於白鍵略高或略低的音;在音樂上會把這個略高、略低的音程(音的距離)叫做一個 半音

我們在生活中常常口語說 高八度、低八度,這個 八度 指的是從自己到下一個同音名音符的距離;從 C 出發的話,沿途會經過 C#、D、D#、E、F、F#、G、G#、A、A#、B、C,共十二個半音。

half step

在數位音樂,我們會從定義 C-1 : 0 開始依序往上,定義 MIDI 編號;例如鋼琴的中央 C1,代號是 24;常用來定調的 A4,則是 69。也可以把 MIDI 編號理解成「這個音符距離 C-1 有幾個半音」這樣。

那麼知道了要播放的聲音是第幾個半音之後,要怎麼換算成頻率呢?

十二平均律

物理上,聲音就是物質震動時的聲波被人耳感知到的物理現象;不同的震動頻率,我們給予它們不同的音名。兩相鄰的同音名的音,其頻率為兩倍(e.g.: A3 = 220hz,A4 = 440hz)。

一個八度,會被分成十二個半音。因此相鄰半音之間的頻率比例為

那麼拼圖湊齊了,就可以開始計算啦~

一個音符音高為 E2,可以換算成第 40 個半音,再利用 A4 = 440hz 作為計算的基準,可以換算出 E2 = 82.4068892282175 hz
...

那麼今天的實作部分,就先把這些計算過程抽成函式,方便後續進行吧~

Demo

首先是計算半音:

getSemitone(note) {
  if(!note || note === '-') return 69
  const noteList = {
    'C': 0,
    'C#': 1,
    'Db': 1,
    'D': 2,
    'D#': 3,
    'Eb': 3,
    'E': 4,
    'F': 5,
    'F#': 6,
    'Gb': 6,
    'G': 7,
    'G#': 8,
    'Ab': 8,
    'A': 9,
    'A#': 10,
    'Bb': 10,
    'B': 11
  }
  return noteList[note.slice(0,-1)] + 12 * (1 + parseInt(note.slice(-1)))
},

考慮了輸入音高時,升降號可能造成的異名同音。

接著是計算頻率:

getFrequency(semitone) {
  return this.standardA4 * Math.pow(2, (semitone - 69)/12)
},

然後寫好切換音符的函式:

changeNoteHandler(note) {
  this.note = note
  this.frequency = this.getFrequency(this.getSemitone(note))
  this.setNoteConfig()
},

到這邊,頻率計算相關的部分也就告一段落啦!那今天也就先到這,大家明天見~

筆者

Gary

半路出家網站工程師;半生熟的前端加上一點點的後端。
喜歡音樂,喜歡學習、分享,也喜歡當個遊戲宅。

相信一切安排都是最好的路。


上一篇
03. Web Audio API - 節點關係
下一篇
05. 吉他定音器 - Part.2
系列文
JavaScript 音樂漫遊 - 30 天探索 Web Audio!31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言